package carSearch

import (
	"car-thirdparty-api/internal/consts"
	"car-thirdparty-api/internal/dao"
	"car-thirdparty-api/internal/model"
	"car-thirdparty-api/internal/types"
	"context"
	"github.com/gogf/gf/v2/database/gdb"
	"sort"
	"sync"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

func CarSearch(r *ghttp.Request) {
	ctx := r.GetCtx()
	g.Log().Debug(ctx, "car search")

	var req types.CarSearchReq
	err := r.Parse(&req)
	if err != nil {
		g.Log().Error(ctx, "car search parse error", err)
		r.Response.Write(g.Map{"success": "false", "message": "请求数据为空"})
		return
	}
	g.Log().Debug(ctx, "car search req data", req)

	resData := make([]types.CarSearchRes, 0)
	var wg sync.WaitGroup
	wg.Add(4)
	go queryCard(ctx, req.Plate, &resData, &wg)
	go queryCardOnline(ctx, req.Plate, &resData, &wg)
	go queryOrder(ctx, req.Plate, &resData, &wg)
	//go queryTempOnline(ctx, req.Plate, &resData, &wg)
	go queryBlackList(ctx, req.Plate, &resData, &wg)
	wg.Wait()

	// 根据Age字段进行排序
	sort.Slice(resData, func(i, j int) bool {
		return resData[i].DataType < resData[j].DataType
	})

	res := g.Map{
		"success": "true",
		"message": "请求成功",
		"data":    resData,
	}

	r.Response.WriteJsonExit(res)
}

func CarAppSearch(r *ghttp.Request) {
	ctx := r.GetCtx()
	g.Log().Debug(ctx, "car search")

	var req types.CarSearchReq
	err := r.Parse(&req)
	if err != nil {
		g.Log().Error(ctx, "car search parse error", err)
		r.Response.Write(g.Map{"success": "false", "message": "请求数据为空"})
		return
	}
	g.Log().Debug(ctx, "car search req data", req)

	res := g.Map{
		"Code":    500,
		"success": "false",
		"message": "查询失败",
		"data":    nil,
	}
	resData := queryAppCard(ctx, req.Plate)
	if resData != nil {
		res = g.Map{
			"Code":    200,
			"success": "true",
			"message": "查询成功",
			"data":    resData,
		}
		goto end
	}

	resData = queryAppCardOnline(ctx, req.Plate)
	if resData != nil {
		res = g.Map{
			"Code":    200,
			"success": "true",
			"message": "查询成功",
			"data":    resData,
		}
		goto end
	}

	resData = queryAppOrder(ctx, req.Plate)
	if resData != nil {
		res = g.Map{
			"Code":    200,
			"success": "true",
			"message": "查询成功",
			"data":    resData,
		}
		goto end
	}

	resData = queryAppBlackList(ctx, req.Plate)
	if resData != nil {
		res = g.Map{
			"Code":    200,
			"success": "true",
			"message": "查询成功",
			"data":    resData,
		}
		goto end
	}

	res = g.Map{
		"Code":    200,
		"success": "true",
		"message": "查询成功",
		"data":    nil,
	}

end:
	r.Response.WriteJsonExit(res)
	return
}

// 查询办证信息表
func queryCard(ctx context.Context, plate string, list *[]types.CarSearchRes, wg *sync.WaitGroup) (resData *types.CarSearchRes) {
	var cardList []*model.CardSearch

	err := dao.Card.Ctx(ctx).
		WhereLike(dao.Card.Columns().CarNum, "%"+plate+"%").
		WhereNotIn(dao.Card.Columns().Flag, []int{3, 13}).
		OrderDesc(dao.Card.Columns().CreateTime).
		//Limit(1).
		Scan(&cardList)
	if err != nil {
		g.Log().Error(ctx, "查询办证信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "JobId")).
		ScanList(&cardList, "BUser", "Card", "user_name:JobId")
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "CreateBy")).
		ScanList(&cardList, "CUser", "Card", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardList, "UpdateBy")).
		ScanList(&cardList, "UUser", "Card", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(cardList, "DeptId")).
		ScanList(&cardList, "Dept", "Card", "dept_id:DeptId")
	if err != nil {
		return nil
	}

	for _, card := range cardList {
		resData = &types.CarSearchRes{
			CarNum:   card.CarNum,
			DataType: consts.Card,
			Identity: card.CarId,
			Name:     card.CardName,
			PhoneNum: card.CardTel,
			JobId:    card.JobId,
		}
		if card.BUser != nil {
			resData.BUserName = card.BUser.NickName
		}
		if card.CUser != nil {
			resData.CUserName = card.CUser.NickName
		}
		if card.UUser != nil {
			resData.UUserName = card.UUser.NickName
		}
		if card.Dept != nil {
			resData.DeptName = card.Dept.DeptName
		}
		*list = append(*list, *resData)
	}

	g.Log().Debug(ctx, "查询办证信息成功，done")
	wg.Done()
	return
}

// 查询月租车信息表
func queryCardOnline(ctx context.Context, plate string, list *[]types.CarSearchRes, wg *sync.WaitGroup) (resData *types.CarSearchRes) {
	var cardOnlineList []*model.CardOnlineSearch
	err := dao.CardOnline.Ctx(ctx).
		WhereLike(dao.CardOnline.Columns().CarNum, "%"+plate+"%").
		OrderDesc(dao.CardOnline.Columns().CreateTime).
		Scan(&cardOnlineList)
	if err != nil {
		g.Log().Error(ctx, "查询月租车信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardOnlineList, "CreateBy")).
		ScanList(&cardOnlineList, "CUser", "CardOnline", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(cardOnlineList, "UpdateBy")).
		ScanList(&cardOnlineList, "UUser", "CardOnline", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(cardOnlineList, "DeptId")).
		ScanList(&cardOnlineList, "Dept", "CardOnline", "dept_id:DeptId")
	if err != nil {
		return nil
	}

	for _, cardOnline := range cardOnlineList {
		resData = &types.CarSearchRes{
			CarNum:   cardOnline.CarNum,
			DataType: consts.CardOnline,
			Identity: cardOnline.CardIdNum,
			Name:     cardOnline.CardName,
			PhoneNum: cardOnline.CardTel,
		}

		if cardOnline.CUser != nil {
			resData.CUserName = cardOnline.CUser.NickName
		}
		if cardOnline.UUser != nil {
			resData.UUserName = cardOnline.UUser.NickName
		}
		if cardOnline.Dept != nil {
			resData.DeptName = cardOnline.Dept.DeptName
		}
		*list = append(*list, *resData)
	}

	g.Log().Debug(ctx, "查询月租信息成功，done")
	wg.Done()
	return
}

// 查询预约车信息表
func queryOrder(ctx context.Context, plate string, list *[]types.CarSearchRes, wg *sync.WaitGroup) (resData *types.CarSearchRes) {
	var bookingCardList []*model.BookingCardSearch
	err := dao.BookingCard.Ctx(ctx).
		WhereLike(dao.BookingCard.Columns().CarNum, "%"+plate+"%").
		OrderDesc(dao.BookingCard.Columns().CreateTime).
		Scan(&bookingCardList)
	if err != nil {
		g.Log().Error(ctx, "查询预约车信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(bookingCardList, "CreateBy")).
		ScanList(&bookingCardList, "CUser", "BookingCard", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(bookingCardList, "UpdateBy")).
		ScanList(&bookingCardList, "UUser", "BookingCard", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(bookingCardList, "DeptId")).
		ScanList(&bookingCardList, "Dept", "BookingCard", "dept_id:DeptId")
	if err != nil {
		return nil
	}

	for _, bookingCard := range bookingCardList {
		resData = &types.CarSearchRes{
			CarNum:   bookingCard.CarNum,
			DataType: consts.BookingCard,
			Identity: "",
			Name:     bookingCard.OrderUser,
			PhoneNum: bookingCard.OrderTel,
		}

		if bookingCard.CUser != nil {
			resData.CUserName = bookingCard.CUser.NickName
		}
		if bookingCard.UUser != nil {
			resData.UUserName = bookingCard.UUser.NickName
		}
		if bookingCard.Dept != nil {
			resData.DeptName = bookingCard.Dept.DeptName
		}
		*list = append(*list, *resData)
	}

	g.Log().Debug(ctx, "查询预约信息成功，done")
	wg.Done()
	return
}

// 查询临时车包月信息表
func queryTempOnline(ctx context.Context, plate string, list *[]types.CarSearchRes, wg *sync.WaitGroup) (resData *types.CarSearchRes) {
	var tempOnlineList []*model.TempOnlineSearch
	err := dao.TempOnline.Ctx(ctx).
		WhereLike(dao.TempOnline.Columns().CarNum, "%"+plate+"%").
		OrderDesc(dao.TempOnline.Columns().CreateTime).
		Scan(&tempOnlineList)
	if err != nil {
		g.Log().Error(ctx, "查询临时车包月信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(tempOnlineList, "CreateBy")).
		ScanList(&tempOnlineList, "CUser", "TempOnline", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(tempOnlineList, "UpdateBy")).
		ScanList(&tempOnlineList, "UUser", "TempOnline", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Where("dept_id", gdb.ListItemValuesUnique(tempOnlineList, "DeptId")).
		ScanList(&tempOnlineList, "Dept", "TempOnline", "dept_id:DeptId")
	if err != nil {
		return nil
	}

	for _, tempOnline := range tempOnlineList {
		resData = &types.CarSearchRes{
			CarNum:   tempOnline.CarNum,
			DataType: consts.TempOnline,
			Identity: tempOnline.CardIdNum,
			Name:     tempOnline.CardName,
			PhoneNum: tempOnline.CardTel,
		}
		if tempOnline.CUser != nil {
			resData.CUserName = tempOnline.CUser.NickName
		}
		if tempOnline.UUser != nil {
			resData.UUserName = tempOnline.UUser.NickName
		}
		if tempOnline.Dept != nil {
			resData.DeptName = tempOnline.Dept.DeptName
		}
		*list = append(*list, *resData)
	}

	g.Log().Debug(ctx, "查询外部车包月信息成功，done")
	wg.Done()
	return
}

// 查询黑名单信息表
func queryBlackList(ctx context.Context, plate string, list *[]types.CarSearchRes, wg *sync.WaitGroup) (resData *types.CarSearchRes) {
	var blackListList []*model.BlackListSearch
	err := dao.BlackListRecord.Ctx(ctx).
		WhereLike(dao.BlackListRecord.Columns().CarNum, "%"+plate+"%").
		OrderDesc(dao.BlackListRecord.Columns().CreateTime).
		Scan(&blackListList)
	if err != nil {
		g.Log().Error(ctx, "查询黑名单信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Where("user_name", gdb.ListItemValuesUnique(blackListList, "CreateBy")).
		ScanList(&blackListList, "CUser", "BlackListRecord", "user_name:CreateBy")
	if err != nil {
		return nil
	}

	for _, blackList := range blackListList {
		resData = &types.CarSearchRes{
			CarNum:   blackList.CarNum,
			DataType: consts.BlackList,
			Identity: "",
			Name:     "",
			PhoneNum: "",
		}
		if blackList.CUser != nil {
			resData.CUserName = blackList.CUser.NickName
		}

		*list = append(*list, *resData)
	}

	g.Log().Debug(ctx, "查询黑名单信息成功，done")
	wg.Done()
	return
}

// 查询办证信息表
func queryAppCard(ctx context.Context, plate string) (resData *types.CarSearchRes) {
	var card *model.CardSearch

	err := dao.Card.Ctx(ctx).
		Where(dao.Card.Columns().CarNum, plate).
		WhereNotIn(dao.Card.Columns().Flag, []int{3, 13}).
		Limit(1).
		Scan(&card)
	if err != nil {
		g.Log().Error(ctx, "查询办证信息失败, ", err)
	}

	// 动态关联绑定
	err = g.Model("sys_user").Scan(&card.BUser, "user_name", card.Card.JobId)
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Scan(&card.CUser, "user_name", card.Card.CreateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Scan(&card.UUser, "user_name", card.Card.UpdateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Scan(&card.Dept, "dept_id", card.Card.DeptId)
	if err != nil {
		return nil
	}

	if card != nil {
		resData = &types.CarSearchRes{
			CarNum:   card.CarNum,
			DataType: consts.Card,
			Identity: card.CarId,
			Name:     card.CardName,
			PhoneNum: card.CardTel,
			JobId:    card.JobId,
		}
		if card.BUser != nil {
			resData.BUserName = card.BUser.NickName
		}
		if card.CUser != nil {
			resData.CUserName = card.CUser.NickName
		}
		if card.UUser != nil {
			resData.UUserName = card.UUser.NickName
		}
		if card.Dept != nil {
			resData.DeptName = card.Dept.DeptName
		}
	}

	return
}

// 查询月租车信息表
func queryAppCardOnline(ctx context.Context, plate string) (resData *types.CarSearchRes) {
	var cardOnline *model.CardOnlineSearch
	err := dao.CardOnline.Ctx(ctx).
		Where(dao.CardOnline.Columns().CarNum, plate).
		Limit(1).
		Scan(&cardOnline)
	if err != nil {
		g.Log().Error(ctx, "查询月租车信息失败, ", err)
	}

	// 动态关联绑定
	err = g.Model("sys_user").Scan(&cardOnline.CUser, "user_name", cardOnline.CardOnline.CreateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Scan(&cardOnline.UUser, "user_name", cardOnline.CardOnline.UpdateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Scan(&cardOnline.Dept, "dept_id", cardOnline.CardOnline.DeptId)
	if err != nil {
		return nil
	}

	if cardOnline != nil {
		resData = &types.CarSearchRes{
			CarNum:   cardOnline.CarNum,
			DataType: consts.CardOnline,
			Identity: cardOnline.CardIdNum,
			Name:     cardOnline.CardName,
			PhoneNum: cardOnline.CardTel,
		}
		if cardOnline.CUser != nil {
			resData.CUserName = cardOnline.CUser.NickName
		}
		if cardOnline.UUser != nil {
			resData.UUserName = cardOnline.UUser.NickName
		}
		if cardOnline.Dept != nil {
			resData.DeptName = cardOnline.Dept.DeptName
		}
	}
	return
}

// 查询预约车信息表
func queryAppOrder(ctx context.Context, plate string) (resData *types.CarSearchRes) {
	var bookingCard *model.BookingCardSearch
	err := dao.BookingCard.Ctx(ctx).
		Where(dao.BookingCard.Columns().CarNum, plate).
		OrderDesc(dao.BookingCard.Columns().CreateTime).
		Limit(1).
		Scan(&bookingCard)
	if err != nil {
		g.Log().Error(ctx, "查询预约车信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Scan(&bookingCard.CUser, "user_name", bookingCard.BookingCard.CreateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_user").Scan(&bookingCard.UUser, "user_name", bookingCard.BookingCard.UpdateBy)
	if err != nil {
		return nil
	}

	err = g.Model("sys_dept").Scan(&bookingCard.Dept, "dept_id", bookingCard.BookingCard.DeptId)
	if err != nil {
		return nil
	}

	if bookingCard != nil {
		resData = &types.CarSearchRes{
			CarNum:   bookingCard.CarNum,
			DataType: consts.BookingCard,
			Identity: "",
			Name:     bookingCard.OrderUser,
			PhoneNum: bookingCard.OrderTel,
		}
		if bookingCard.CUser != nil {
			resData.CUserName = bookingCard.CUser.NickName
		}
		if bookingCard.UUser != nil {
			resData.UUserName = bookingCard.UUser.NickName
		}
		if bookingCard.Dept != nil {
			resData.DeptName = bookingCard.Dept.DeptName
		}
	}

	return
}

// 查询黑名单信息表
func queryAppBlackList(ctx context.Context, plate string) (resData *types.CarSearchRes) {
	var blackList *model.BlackListSearch
	err := dao.BlackListRecord.Ctx(ctx).
		Where(dao.BlackListRecord.Columns().CarNum, plate).
		OrderDesc(dao.BlackListRecord.Columns().CreateTime).
		Limit(1).
		Scan(&blackList)
	if err != nil {
		g.Log().Error(ctx, "查询黑名单信息失败, ", err)
	}

	// 动态关联查询人员信息和部门信息
	err = g.Model("sys_user").Scan(&blackList.CUser, "user_name", blackList.BlackListRecord.CreateBy)
	if err != nil {
		return nil
	}

	if blackList != nil {
		resData = &types.CarSearchRes{
			CarNum:   blackList.CarNum,
			DataType: consts.BlackList,
			Identity: "",
			Name:     "",
			PhoneNum: "",
		}
		if blackList.CUser != nil {
			resData.CUserName = blackList.CUser.NickName
		}
	}
	return
}
